/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.client.user;

import net.bioteam.appweb.gwt.apps.client.StaticHolder;
import net.bioteam.appweb.gwt.apps.client.Util.ApplicationCallBack;
import net.bioteam.appweb.gwt.apps.client.Util.GwtRpcDataSource;
import net.bioteam.appweb.gwt.apps.clientandserver.user.AdminUserAction;
import net.bioteam.appweb.gwt.apps.clientandserver.user.UserRet;
import net.bioteam.common.user.User;

import com.google.gwt.core.client.JavaScriptObject;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.SortSpecifier;
import com.smartgwt.client.data.fields.DataSourceBooleanField;
import com.smartgwt.client.data.fields.DataSourceEnumField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.types.FieldType;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.grid.ListGridRecord;

public class UsersDataSource extends GwtRpcDataSource
{

	private static void copyValues(User user, ListGridRecord to)
	{
		to.setAttribute("userid", user.getUserid());
		to.setAttribute("name", user.getName());
		to.setAttribute("email", user.getEmail());
		to.setAttribute("role", user.getRole());
		to.setAttribute("password", user.getPassword());
		to.setAttribute("active", user.isActive());
		to.setAttribute("ec2user", user.hasECCredential());
		to.setAttribute("dailyquote", user.getUserInfo().getDailyquote());
		
		
	}

	private static void copyValues(ListGridRecord to, User user)
	{
		if (to.getAttribute("userid")!=null)
			user.setUserid(to.getAttributeAsInt("userid"));
		user.setName(to.getAttributeAsString("name"));
		user.setEmail(to.getAttributeAsString("email"));
		if (to.getAttribute("role")!=null)
			user.setRole(to.getAttributeAsString("role"));
		user.setPassword(to.getAttributeAsString("password"));
		
		if (to.getAttributeAsBoolean("active"))
		{
			user.setActive(true);
		} else
		{
			user.setActive(false);
		}
		user.getUserInfo().setDailyquote(Integer.parseInt(to.getAttributeAsString("dailyquote")));
	}

	public UsersDataSource()
	{
		super();
		DataSourceTextField idField = new DataSourceTextField("userid");
		idField.setPrimaryKey(true);
		idField.setHidden(true);

		DataSourceTextField nameField = new DataSourceTextField("name");
		nameField.setCanEdit(false);

		DataSourceTextField passwordField = new DataSourceTextField("password");
		passwordField.setType(FieldType.PASSWORD);

		DataSourceTextField emailField = new DataSourceTextField("email");

		DataSourceEnumField roleField = new DataSourceEnumField("role");
		roleField.setValueMap("admin", "user");
		
		DataSourceIntegerField quotaField = new DataSourceIntegerField("dailyquote");
		
		
		DataSourceBooleanField activeField=new DataSourceBooleanField("active");

		setFields(idField, nameField, emailField, roleField, activeField);
	}

	@Override
	protected void executeAdd(final String requestId, final DSRequest request, final DSResponse response)
	{
		JavaScriptObject data = request.getData();
		ListGridRecord rec = new ListGridRecord(data);
		final User user = new User();
		copyValues(rec, user);
		ApplicationCallBack<User> callback = new ApplicationCallBack<User>()
		{
			public void onFailureAfter(Throwable caught)
			{
				response.setStatus(RPCResponse.STATUS_FAILURE);
				processResponse(requestId, response);
				SC.warn(caught.getMessage(), StaticHolder.dumpB);
			}

			public void onSuccessAfter(User result)
			{
				ListGridRecord[] list = new ListGridRecord[1];
				ListGridRecord newRec = new ListGridRecord();
				copyValues(result, newRec);
				list[0] = newRec;
				response.setData(list);
				processResponse(requestId, response);

			}

			public void execute()
			{
				AdminUserAction.Util.getInstance().addUser(user, this);
			}

		};
		callback.execute();

	}

	@Override
	protected void executeFetch(final String requestId, final DSRequest request, final DSResponse response)
	{
		ApplicationCallBack<UserRet> callback = new ApplicationCallBack<UserRet>()
		{
			public void onFailureAfter(Throwable caught)
			{
				response.setStatus(RPCResponse.STATUS_FAILURE);
				processResponse(requestId, response);
				SC.warn(caught.getMessage(), StaticHolder.dumpB);
			}

			public void onSuccessAfter(UserRet result)
			{
				ListGridRecord[] list = new ListGridRecord[result.users.length];
				for (int i = 0; i < list.length; i++)
				{
					ListGridRecord record = new ListGridRecord();
					copyValues(result.users[i], record);
					list[i] = record;
				}
				response.setData(list);
				// IMPORTANT: for paging to work we have to specify size of full
				// result set
				response.setStartRow(request.getStartRow());
				response.setEndRow(request.getStartRow()+list.length);
                response.setTotalRows (result.count);
				processResponse(requestId, response);

			}

			public void execute()
			{
						
				String sort =null;
				String direction = "asc";
				if (request.getSortBy()!=null && request.getSortBy().length>0)
				{
					SortSpecifier ss=request.getSortBy()[0];
					sort=ss.getField();
					direction=ss.getSortDirection().getValue();
				}
				AdminUserAction.Util.getInstance().getUsers(request.getStartRow(), request.getEndRow() - request.getStartRow(), sort, direction, this);
			}

		};
		callback.execute();
	}

	@Override
	protected void executeRemove(final String requestId, final DSRequest request, final DSResponse response)
	{
		response.setStatus(RPCResponse.STATUS_FAILURE);
		processResponse(requestId, response);

		//no deletion is allowed
//		JavaScriptObject data = request.getData();
//		final ListGridRecord rec = new ListGridRecord(data);
//		ApplicationCallBack<String> callback = new ApplicationCallBack<String>()
//		{
//			public void onFailureAfter(Throwable caught)
//			{
//				response.setStatus(RPCResponse.STATUS_FAILURE);
//				processResponse(requestId, response);
//				SC.warn(caught.getMessage(), StaticHolder.dumpB);
//			}
//
//			public void onSuccessAfter(String result)
//			{
//				ListGridRecord[] list = new ListGridRecord[1];
//				// We do not receive removed record from server.
//				// Return record from request.
//				list[0] = rec;
//				response.setData(list);
//				processResponse(requestId, response);
//
//			}
//
//			public void execute()
//			{
//
//				String ids[] = new String[1];
//				ids[0] = rec.getAttributeAsString("userid");
//				UserAction.Util.getInstance().deleteUsers(ids, this);
//			}
//
//		};
//		callback.execute();

	}

	@Override
	protected void executeUpdate(final String requestId, final DSRequest request, final DSResponse response)
	{
		ListGridRecord rec = getEditedRecord(request);
		final User user = new User();
		copyValues(rec, user);
		ApplicationCallBack<User[]> callback = new ApplicationCallBack<User[]>()
		{
			public void onFailureAfter(Throwable caught)
			{
				response.setStatus(RPCResponse.STATUS_FAILURE);
				processResponse(requestId, response);
				SC.warn(caught.getMessage(), StaticHolder.dumpB);
			}

			public void onSuccessAfter(User[] result)
			{
				ListGridRecord[] list = new ListGridRecord[1];
				ListGridRecord updRec = new ListGridRecord();
				copyValues(result[0], updRec);
				list[0] = updRec;
				response.setData(list);
				processResponse(requestId, response);
			}

			public void execute()
			{
				User[] users = new User[1];
				users[0] = user;
				AdminUserAction.Util.getInstance().saveUsers(users, this);
			}

		};
		callback.execute();

	}

}
